﻿using System.ComponentModel;
using GurLoader.Util;

namespace GurLoader.Service
{
    public class CommandProgress : ICommandProgress
    {
        private static readonly PropertyChangedEventArgs isCompleteChangeArgs =
            ObservableHelper.CreateArgs<CommandProgress>(x => x.IsComplete);

        private static readonly PropertyChangedEventArgs progressPercentageChangeArgs =
            ObservableHelper.CreateArgs<CommandProgress>(x => x.ProgressPercentage);

        private static readonly PropertyChangedEventArgs statusChangeArgs =
            ObservableHelper.CreateArgs<CommandProgress>(x => x.Status);

        private static readonly PropertyChangedEventArgs contentDescriptionChangeArgs =
            ObservableHelper.CreateArgs<CommandProgress>(x => x.ContentDescription);

        private static readonly PropertyChangedEventArgs isCancelledChangeArgs =
            ObservableHelper.CreateArgs<CommandProgress>(x => x.IsCancelled);

        private int progressPercentage;
        private string status = string.Empty;
        private string contentDescription = string.Empty;
        private bool isCancelled = false;

        public CommandProgress(Command command, int progressPercentage, string contentDescription, string status )
        {
            this.progressPercentage = progressPercentage;
            ContentDescription = contentDescription;
            Command = command;
            Status = status;
        }

        public CommandProgress(Command command, int progressPercentage, string status)
        {
            Command = command;
            ProgressPercentage = progressPercentage;
            Status = status;
        }

        public CommandProgress(Command command, string status, object result)
        {
            Command = command;
            ProgressPercentage = 100;
            Result = result;
            Status = status;
        }

        public virtual bool IsCancelled
        {
            get { return isCancelled; }
            set
            {
                isCancelled = value;
                FireIsCancelledChanged();
            }
        }

        protected void FireIsCancelledChanged()
        {
            NotifyPropertyChanged(isCancelledChangeArgs);
        }

        public string ContentDescription
        {
            get { return contentDescription; }

            set
            {
                contentDescription = value;
                NotifyPropertyChanged(contentDescriptionChangeArgs);
            }
        }

        public Command Command { get; private set; }

        public virtual bool IsComplete
        {
            get { return ProgressPercentage == 100; }
        }

        protected void FireIsCompleteChanged()
        {
            NotifyPropertyChanged(isCompleteChangeArgs);
        }

        public virtual int ProgressPercentage
        {
            get { return progressPercentage; }
            set
            {
                progressPercentage = value;
                FireProgressPercentageChanged();
                if (IsComplete)
                    FireIsCompleteChanged();
            }
        }

        protected void FireProgressPercentageChanged()
        {
            NotifyPropertyChanged(progressPercentageChangeArgs);
        }

        public string Status
        {
            get { return status; }
            set
            {
                status = value;
                NotifyPropertyChanged(statusChangeArgs);
            }
        }

        public object Result { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(PropertyChangedEventArgs args)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, args);
            }
        }
    }
}